import random
import threading
import time
import vgamepad
from pynput import keyboard, mouse
from yangke.common.config import logger

# XBOX手柄左边方向键的上下左右
KEYUP = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_UP  # KEY表示这个上下左右是按键，不是摇杆，摇杆是模拟量输入，KEY是开关量
KEYDOWN = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_DOWN
KEYLEFT = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_LEFT
KEYRIGHT = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_DPAD_RIGHT

A = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_A
B = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_B
X = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_X
Y = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_Y

START = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_START
BACK = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_BACK
GUIDE = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_GUIDE

LB = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_LEFT_SHOULDER  # LB键，左肩键
RB = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_RIGHT_SHOULDER

LSB = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_LEFT_THUMB  # 左摇杆按下键，LSB键，左摇杆本身也可以按下，作为一个按键使用
RSB = vgamepad.XUSB_BUTTON.XUSB_GAMEPAD_RIGHT_THUMB


class GamePad:
    def __init__(self):
        self.gamepad: vgamepad.VX360Gamepad | None = None
        # 创建按钮映射字典
        self.button_map = {
            "A": A,
            "B": B,
            "X": X,
            "Y": Y,
            "START": START,
            "BACK": BACK,
            "GUIDE": GUIDE,
            "KEYLEFT": KEYLEFT,
            "KEYRIGHT": KEYRIGHT,
            "KEYUP": KEYUP,
            "KEYDOWN": KEYDOWN,
            "LB": LB,
            "RB": RB,
            "LSB": LSB,
            "RSB": RSB,
        }
        # 存储摇杆当前值
        self.left_joystick_x = 0.0
        self.left_joystick_y = 0.0
        self.right_joystick_x = 0.0
        self.right_joystick_y = 0.0
        self.left_trigger = 0.0
        self.right_trigger = 0.0

    def plugin_game_pad(self):
        self.gamepad = vgamepad.VX360Gamepad()
        return self.gamepad

    def pullout_game_pad(self):
        # 移除虚拟手柄
        if self.gamepad:
            # 重置手柄状态
            self.gamepad.reset()
            self.gamepad.update()
            # 删除手柄对象
            del self.gamepad
            self.gamepad = None

    def set_left_joystick_x(self, x_value):
        """设置左侧摇杆X轴值，范围-1.0到1.0"""
        if self.gamepad:
            self.left_joystick_x = max(-1.0, min(1.0, x_value))
            self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            self.gamepad.update()

    def set_left_joystick_y(self, y_value):
        """设置左侧摇杆Y轴值，范围-1.0到1.0"""
        if self.gamepad:
            self.left_joystick_y = max(-1.0, min(1.0, y_value))
            self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            self.gamepad.update()

    def set_right_joystick_x(self, x_value):
        """设置右侧摇杆X轴值，范围-1.0到1.0"""
        if self.gamepad:
            self.right_joystick_x = max(-1.0, min(1.0, x_value))
            self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            self.gamepad.update()

    def set_right_joystick_y(self, y_value):
        """设置右侧摇杆Y轴值，范围-1.0到1.0"""
        if self.gamepad:
            self.right_joystick_y = max(-1.0, min(1.0, y_value))
            self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            self.gamepad.update()

    def set_left_trigger(self, value):
        """设置左扳机键值，范围0.0到1.0"""
        if self.gamepad:
            self.left_trigger = max(0.0, min(1.0, value))
            self.gamepad.left_trigger_float(self.left_trigger)
            self.gamepad.update()

    def set_right_trigger(self, value):
        """设置右扳机键值，范围0.0到1.0"""
        if self.gamepad:
            self.right_trigger = max(0.0, min(1.0, value))
            self.gamepad.right_trigger_float(self.right_trigger)
            self.gamepad.update()

    def press_button(self, btn):
        """按下虚拟手柄按键"""
        logger.debug(f"按下手柄按键: {btn}")
        if btn in self.button_map and self.gamepad:
            button = self.button_map[btn]
            self.gamepad.press_button(button)
            self.gamepad.update()
        elif btn in ["LJOY_UP", "LJOY_LEFT", "LJOY_DOWN", "LJOY_RIGHT", "RJOY_UP", "RJOY_LEFT", "RJOY_DOWN",
                     "RJOY_RIGHT", "LT", "RT"]:
            # 摇杆操作

            if btn == "LJOY_UP":
                if self.left_joystick_y < 0.5:
                    self.left_joystick_y = self.random_float()
                self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            elif btn == "LJOY_DOWN":
                if self.left_joystick_y > -0.5:
                    self.left_joystick_y = -self.random_float()
                self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            elif btn == "LJOY_LEFT":
                if self.left_joystick_x > -0.5:
                    self.left_joystick_x = -self.random_float()
                self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            elif btn == "LJOY_RIGHT":
                if self.left_joystick_x < 0.5:
                    self.left_joystick_x = self.random_float()
                self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            elif btn == "RJOY_UP":
                if self.right_joystick_y < 0.5:
                    self.right_joystick_y = self.random_float()
                self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            elif btn == "RJOY_DOWN":
                if self.right_joystick_y > -0.5:
                    self.right_joystick_y = -self.random_float()
                self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            elif btn == "RJOY_LEFT":
                if self.right_joystick_x > -0.5:
                    self.right_joystick_x = -self.random_float()
                self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            elif btn == "RJOY_RIGHT":
                if self.right_joystick_x < 0.5:
                    self.right_joystick_x = self.random_float()
                self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            elif btn == "LT":
                if self.left_trigger < 0.5:
                    self.left_trigger = self.random_float()
                self.gamepad.left_trigger_float(self.left_trigger)
            elif btn == "RT":
                if self.right_trigger < 0.5:
                    self.right_trigger = self.random_float()
                self.gamepad.right_trigger_float(self.right_trigger)
            self.gamepad.update()
            # logger.debug(f"摇杆参数：{self.left_joystick_x}, {self.left_joystick_y}")
        else:
            logger.debug(f"Invalid button：{btn}")

    @staticmethod
    def random_float():
        """随机生成一个数，表示摇杆的输入程度，摇杆是模拟量，所以可以表示方向的程度"""
        return random.uniform(0.98, 1)

    def release_button(self, btn):
        # 释放虚拟手柄按键
        if btn in self.button_map and self.gamepad:
            button = self.button_map[btn]
            self.gamepad.release_button(button)
            logger.info(f"释放按键：{btn}")
            self.gamepad.update()
        elif btn in ["LJOY_UP", "LJOY_LEFT", "LJOY_DOWN", "LJOY_RIGHT", "RJOY_UP", "RJOY_LEFT", "RJOY_DOWN",
                     "RJOY_RIGHT", "LT", "RT"]:
            # 摇杆操作
            if btn in ["LJOY_UP", "LJOY_DOWN"]:
                # 将摇杆的y值设置为0，x值保持不变
                self.left_joystick_y = 0
                self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            elif btn in ["LJOY_LEFT", "LJOY_RIGHT"]:
                # 将摇杆的y值设置为0，x值保持不变
                self.left_joystick_x = 0
                self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
            elif btn in ["RJOY_UP", "RJOY_DOWN"]:
                # 将摇杆的x值设置为0，y值保持不变
                self.right_joystick_y = 0
                self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            elif btn in ["RJOY_LEFT", "RJOY_RIGHT"]:
                self.right_joystick_x = 0
                self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
            elif btn == "LT":
                self.left_trigger = 0
                self.gamepad.left_trigger_float(self.left_trigger)
            elif btn == "RT":
                self.right_trigger = 0
                self.gamepad.right_trigger_float(self.right_trigger)
            self.gamepad.update()
            # logger.debug(f"release_button-摇杆参数：{self.left_joystick_x}, {self.left_joystick_y}")
        else:
            logger.debug(f"Invalid button：{btn}")

    def btn_clicked(self, btn):
        # 按下并释放虚拟手柄按键
        if btn in self.button_map and self.gamepad:
            button = self.button_map[btn]
            self.gamepad.press_button(button)
            self.gamepad.update()
            self.gamepad.release_button(button)
            self.gamepad.update()
        else:
            logger.debug("Invalid button")

    def reset(self):
        # 将虚拟手柄状态重置
        if self.gamepad:
            self.gamepad.reset()

        # 重置存储的摇杆和扳机值
        self.left_joystick_x = 0.0
        self.left_joystick_y = 0.0
        self.right_joystick_x = 0.0
        self.right_joystick_y = 0.0
        self.left_trigger = 0.0
        self.right_trigger = 0.0
        # self.gamepad.left_joystick_float(self.left_joystick_x, self.left_joystick_y)
        # self.gamepad.update()
        # self.gamepad.right_joystick_float(self.right_joystick_x, self.right_joystick_y)
        # self.gamepad.update()
        # self.gamepad.right_trigger_float(self.right_trigger)
        # self.gamepad.update()
        # self.gamepad.left_trigger_float(self.left_trigger)
        # self.gamepad.update()


class GamePadManager:
    # 在类的开头添加这些常量
    GAMEPAD_BUTTONS = [
        'A', 'B', 'X', 'Y', 'START', 'BACK', 'GUIDE',
        'KEYUP', 'KEYDOWN', 'KEYLEFT', 'KEYRIGHT',
        'LB', 'RB', 'LSB', 'RSB'
    ]

    JOYSTICK_BUTTONS = [
        'LJOY_UP', 'LJOY_DOWN', 'LJOY_LEFT', 'LJOY_RIGHT',
        'RJOY_UP', 'RJOY_DOWN', 'RJOY_LEFT', 'RJOY_RIGHT',
        'LT', 'RT'
    ]

    KEYBOARD_KEYS = {
        'a': keyboard.KeyCode.from_char('a'),
        'b': keyboard.KeyCode.from_char('b'),
        'c': keyboard.KeyCode.from_char('c'),
        'd': keyboard.KeyCode.from_char('d'),
        'e': keyboard.KeyCode.from_char('e'),
        'f': keyboard.KeyCode.from_char('f'),
        'g': keyboard.KeyCode.from_char('g'),
        'h': keyboard.KeyCode.from_char('h'),
        'i': keyboard.KeyCode.from_char('i'),
        'j': keyboard.KeyCode.from_char('j'),
        'k': keyboard.KeyCode.from_char('k'),
        'l': keyboard.KeyCode.from_char('l'),
        'm': keyboard.KeyCode.from_char('m'),
        'n': keyboard.KeyCode.from_char('n'),
        'o': keyboard.KeyCode.from_char('o'),
        'p': keyboard.KeyCode.from_char('p'),
        'q': keyboard.KeyCode.from_char('q'),
        'r': keyboard.KeyCode.from_char('r'),
        's': keyboard.KeyCode.from_char('s'),
        't': keyboard.KeyCode.from_char('t'),
        'u': keyboard.KeyCode.from_char('u'),
        'v': keyboard.KeyCode.from_char('v'),
        'w': keyboard.KeyCode.from_char('w'),
        'x': keyboard.KeyCode.from_char('x'),
        'y': keyboard.KeyCode.from_char('y'),
        'z': keyboard.KeyCode.from_char('z'),
        '0': keyboard.KeyCode.from_char('0'),
        '1': keyboard.KeyCode.from_char('1'),
        '2': keyboard.KeyCode.from_char('2'),
        '3': keyboard.KeyCode.from_char('3'),
        '4': keyboard.KeyCode.from_char('4'),
        '5': keyboard.KeyCode.from_char('5'),
        '6': keyboard.KeyCode.from_char('6'),
        '7': keyboard.KeyCode.from_char('7'),
        '8': keyboard.KeyCode.from_char('8'),
        '9': keyboard.KeyCode.from_char('9'),
        'space': keyboard.Key.space,
        'enter': keyboard.Key.enter,
        'esc': keyboard.Key.esc,
        'tab': keyboard.Key.tab,
        'capslock': keyboard.Key.caps_lock,
        'shift': keyboard.Key.shift,
        'ctrl': keyboard.Key.ctrl,
        'alt': keyboard.Key.alt,
        'lctrl': keyboard.Key.ctrl_l,
        'rctrl': keyboard.Key.ctrl_r,
        'lshift': keyboard.Key.shift_l,
        'rshift': keyboard.Key.shift_r,
        'lalt': keyboard.Key.alt_l,
        'ralt': keyboard.Key.alt_r,
        'win': keyboard.Key.cmd,
        'backspace': keyboard.Key.backspace,
        'delete': keyboard.Key.delete,
        'insert': keyboard.Key.insert,
        'home': keyboard.Key.home,
        'end': keyboard.Key.end,
        'pageup': keyboard.Key.page_up,
        'pagedown': keyboard.Key.page_down,
        'up': keyboard.Key.up,
        'down': keyboard.Key.down,
        'left': keyboard.Key.left,
        'right': keyboard.Key.right,
        'f1': keyboard.Key.f1,
        'f2': keyboard.Key.f2,
        'f3': keyboard.Key.f3,
        'f4': keyboard.Key.f4,
        'f5': keyboard.Key.f5,
        'f6': keyboard.Key.f6,
        'f7': keyboard.Key.f7,
        'f8': keyboard.Key.f8,
        'f9': keyboard.Key.f9,
        'f10': keyboard.Key.f10,
        'f11': keyboard.Key.f11,
        'f12': keyboard.Key.f12,
        'num0': keyboard.KeyCode.from_char('0'),
        'num1': keyboard.KeyCode.from_char('1'),
        'num2': keyboard.KeyCode.from_char('2'),
        'num3': keyboard.KeyCode.from_char('3'),
        'num4': keyboard.KeyCode.from_char('4'),
        'num5': keyboard.KeyCode.from_char('5'),
        'num6': keyboard.KeyCode.from_char('6'),
        'num7': keyboard.KeyCode.from_char('7'),
        'num8': keyboard.KeyCode.from_char('8'),
        'num9': keyboard.KeyCode.from_char('9'),
        'num+': keyboard.KeyCode.from_char('+'),
        'num-': keyboard.KeyCode.from_char('-'),
        'num*': keyboard.KeyCode.from_char('*'),
        'num/': keyboard.KeyCode.from_char('/'),
        'num.': keyboard.KeyCode.from_char('.'),
        'numenter': keyboard.Key.enter,
        'numlock': keyboard.Key.num_lock
    }

    MOUSE_BUTTONS = {
        '鼠标左键': mouse.Button.left,
        '鼠标右键': mouse.Button.right,
        '鼠标滚轮': mouse.Button.middle,
        '鼠标x1键': mouse.Button.x1,
        '鼠标x2键': mouse.Button.x2
    }

    def __init__(self, printToTerm):
        self.printToTerm = printToTerm
        self.gamepad1: GamePad | None = None
        self.gamepad2: GamePad | None = None

        # 游戏手柄模式相关属性
        self.gamepad_mode = "keyboard"  # 默认为键鼠模式
        self.mode_keys = {}

        # 游戏手柄按键映射
        self.gamepad_mapping = {}

        # 定时按键功能设置
        self.timed_key_press_settings = {
            'interval': 1000,  # 毫秒
            'targetKey': '',  # 目标按键
            'hotkey': '',  # 快捷键
            'scope': 'global'  # 作用域 (global, p1, p2)
        }
        self.timed_key_press_active = False  # 定时按键功能是否激活
        self.timed_key_press_timer = None  # 定时器线程

        # 键盘和鼠标监听器
        self.keyboard_listener = None
        self.mouse_listener = None
        self.is_listening = False
        self.mouse_polling_thread = None  # 新增鼠标轮询线程
        self.mouse_polling_active = False  # 新增鼠标轮询激活标志
        # 鼠标控制器，用于重新触发鼠标事件
        self.mouse_controller = mouse.Controller()

        # 反向映射，从键盘/鼠标键到游戏手柄键
        self.reverse_mapping = {}
        self._build_reverse_mapping()

        # 存储当前按下的键
        self.pressed_keys = set()

        self.held_mouse_buttons = {}  # 记录按住的鼠标按键
        self.held_buttons_thread = None
        self.held_buttons_active = False
        self.last_msg = ''

    def _build_reverse_mapping(self):
        """构建从键盘/鼠标键到游戏手柄键的反向映射"""
        self.reverse_mapping = {}
        if self.gamepad_mapping is None:
            return
        for gamepad_key, input_keys in self.gamepad_mapping.items():
            # 如果input_keys是列表（支持多个按键），则为每个按键建立映射
            if isinstance(input_keys, list):
                for input_key in input_keys:
                    if input_key:  # 只处理非空按键
                        self.reverse_mapping[input_key.lower()] = gamepad_key
            else:
                # 原来的单按键处理方式
                if isinstance(input_keys, str):
                    self.reverse_mapping[input_keys.lower()] = gamepad_key

    def insert_game_pads(self):
        """
        添加两个虚拟游戏手柄实例

        :return:
        """
        self.gamepad1 = GamePad()
        self.gamepad1.plugin_game_pad()
        self.gamepad2 = GamePad()
        self.gamepad2.plugin_game_pad()

    def remove_game_pads(self):
        """
        移除两个虚拟游戏手柄实例
        """
        if self.gamepad1:
            self.gamepad1.pullout_game_pad()
            self.gamepad1 = None

        if self.gamepad2:
            self.gamepad2.pullout_game_pad()
            self.gamepad2 = None

        # 停止输入监听
        self.stop_listening()

    def set_gamepad_mode(self, mode):
        """
        设置游戏手柄模式

        :param mode: 模式名称 (p1, p2, sync, keyboard) 或包含快捷键设置的字典
        """
        old_mode = self.gamepad_mode

        if isinstance(mode, str):
            self.gamepad_mode = mode
        elif isinstance(mode, dict):
            # 如果传入的是字典，则更新快捷键设置
            # 确保按键名称是小写的
            normalized_mode = {}
            for k, v in mode.items():
                normalized_mode[k] = v.lower() if isinstance(v, str) else v
            self.mode_keys.update(normalized_mode)

        # 如果从手柄模式切换到键盘模式，确保释放所有按键
        if old_mode != "keyboard" and self.gamepad_mode == "keyboard":
            self._release_all_buttons()

        self.printToTerm(f"游戏手柄模式已设置为: {self.gamepad_mode}")

    def set_gamepad_keys(self, keys: dict):
        """
        设置游戏手柄按键映射

        :param keys: 按键映射字典
        """
        # 确保所有按键名称都是小写的
        normalized_keys = {}
        for k, v in keys.items():
            # 如果v是列表，处理两个按键的情况
            if isinstance(v, list):
                # 只保留非空的按键，最多保留两个
                filtered_keys = [key.lower() for key in v if key]
                if len(filtered_keys) > 2:
                    filtered_keys = filtered_keys[:2]  # 最多保留两个按键
                normalized_keys[k] = filtered_keys
            else:
                normalized_keys[k] = v.lower() if isinstance(v, str) else v

        self.gamepad_mapping.update(normalized_keys)
        self._build_reverse_mapping()
        self.printToTerm("游戏手柄按键映射已更新")

    def set_timed_key_press_settings(self, settings):
        """
        设置定时按键功能参数

        :param settings: 定时按键功能设置字典
        """
        self.timed_key_press_settings.update(settings)
        self.printToTerm(f"定时按键功能设置已更新: {settings}")

    def _toggle_timed_key_press(self):
        """
        切换定时按键功能的启用状态
        """
        self.timed_key_press_active = not self.timed_key_press_active

        if self.timed_key_press_active:
            # 启动定时按键功能
            self._start_timed_key_press()
            self.printToTerm("定时按键功能已启动")
        else:
            # 停止定时按键功能
            self._stop_timed_key_press()
            self.printToTerm("定时按键功能已停止")

    def _start_timed_key_press(self):
        """
        启动定时按键功能
        """
        if self.timed_key_press_timer is not None:
            self._stop_timed_key_press()

        if not self.timed_key_press_settings['targetKey']:
            self.printToTerm("未设置定时按键的目标按键")
            self.timed_key_press_active = False
            return

        self.timed_key_press_timer = threading.Thread(
            target=self._timed_key_press_worker,
            daemon=True
        )
        self.timed_key_press_timer.start()

    def _stop_timed_key_press(self):
        """
        停止定时按键功能
        """
        self.timed_key_press_active = False
        if self.timed_key_press_timer is not None:
            self.timed_key_press_timer = None

    def _timed_key_press_worker(self):
        """
        定时按键工作线程
        """
        interval = self.timed_key_press_settings['interval'] / 1000.0  # 转换为秒
        target_key = self.timed_key_press_settings['targetKey']

        # 当 interval 为 0 时，执行长按操作
        if self.timed_key_press_settings['interval'] == 0:
            # 等待功能停止
            while self.timed_key_press_active:  # 结束线程时会降这个值设为False，从而优雅的退出
                # 一直发送按下按键的事件，防止切换模式时，重置手柄按键状态，导致按下状态丢失
                if self.timed_key_press_settings['scope'].lower() == 'p1':
                    self.gamepad1.press_button(target_key.upper())  # 不管模式，直接按键
                elif self.timed_key_press_settings['scope'].lower() == 'p2':
                    self.gamepad2.press_button(target_key.upper())  # 不管模式，直接按键
                else:
                    self._press_key(target_key)
                time.sleep(0.4)  # 短暂休眠避免占用过多CPU

            # 释放按键
            if self.timed_key_press_settings['scope'].lower() == 'p1':
                self.gamepad1.release_button(target_key.upper())  # 不管模式，直接按键
            elif self.timed_key_press_settings['scope'].lower() == 'p2':
                self.gamepad2.release_button(target_key.upper())  # 不管模式，直接按键
            else:
                self._release_key(target_key)
        else:
            # 原有逻辑：间隔性点击
            while self.timed_key_press_active:
                # 触发目标按键（按下并释放）
                if self.timed_key_press_settings['scope'].lower() == 'p1':
                    self.gamepad1.btn_clicked(target_key.upper())  # 不管模式，直接按键
                elif self.timed_key_press_settings['scope'].lower() == 'p2':
                    self.gamepad2.btn_clicked(target_key.upper())  # 不管模式，直接按键
                else:
                    self._trigger_key(target_key)
                time.sleep(interval)

    def _press_key(self, key):
        """
        按下指定按键但不释放

        :param key: 要按下的按键
        """
        # 根据当前模式按下按键
        if self.gamepad_mode in ["p1", "p2", "sync"]:
            # 手柄模式下触发手柄按键
            if key.upper() in self.GAMEPAD_BUTTONS:
                if self.gamepad_mode == "p1" and self.gamepad1:
                    self.gamepad1.press_button(key.upper())
                elif self.gamepad_mode == "p2" and self.gamepad2:
                    self.gamepad2.press_button(key.upper())
                elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
                    self.gamepad1.press_button(key.upper())
                    self.gamepad2.press_button(key.upper())

            elif key.upper() in self.JOYSTICK_BUTTONS:
                if self.gamepad_mode == "p1" and self.gamepad1:
                    self.gamepad1.press_button(key.upper())
                elif self.gamepad_mode == "p2" and self.gamepad2:
                    self.gamepad2.press_button(key.upper())
                elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
                    self.gamepad1.press_button(key.upper())
                    self.gamepad2.press_button(key.upper())
        else:
            # 键盘鼠标模式下触发键盘或鼠标按键
            # 处理键盘按键
            if key in self.reverse_mapping:
                # 如果这是一个映射的键盘/鼠标按键，触发对应的手柄按键
                gamepad_key = self.reverse_mapping[key]
                self._on_gamepad_key_event(gamepad_key, True)
            else:
                # 处理直接的键盘或鼠标按键
                self._direct_press_key(key)

    def _direct_press_key(self, key):
        """
        直接按下键盘或鼠标按键

        :param key: 要按下的按键
        """
        # 按下键盘按键
        if key.lower() in self.KEYBOARD_KEYS:
            k = self.KEYBOARD_KEYS[key.lower()]
            keyboard.Controller().press(k)

        # 按下鼠标按键
        elif key in self.MOUSE_BUTTONS:
            button = self.MOUSE_BUTTONS[key]
            mouse.Controller().press(button)

    def _direct_release_key(self, key):
        """
        直接释放键盘或鼠标按键

        :param key: 要释放的按键
        """
        # 释放键盘按键
        if key.lower() in self.KEYBOARD_KEYS:
            k = self.KEYBOARD_KEYS[key.lower()]
            keyboard.Controller().release(k)

        # 释放鼠标按键
        elif key in self.MOUSE_BUTTONS:
            button = self.MOUSE_BUTTONS[key]
            mouse.Controller().release(button)

    def _release_key(self, key):
        """
        释放指定按键

        :param key: 要释放的按键
        """
        # 根据当前模式释放按键
        if self.gamepad_mode in ["p1", "p2", "sync"]:
            # 手柄模式下触发手柄按键
            if key.upper() in self.GAMEPAD_BUTTONS:
                if self.gamepad_mode == "p1" and self.gamepad1:
                    self.gamepad1.release_button(key.upper())
                elif self.gamepad_mode == "p2" and self.gamepad2:
                    self.gamepad2.release_button(key.upper())
                elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
                    self.gamepad1.release_button(key.upper())
                    self.gamepad2.release_button(key.upper())

            elif key.upper() in self.JOYSTICK_BUTTONS:
                if self.gamepad_mode == "p1" and self.gamepad1:
                    self.gamepad1.release_button(key.upper())
                elif self.gamepad_mode == "p2" and self.gamepad2:
                    self.gamepad2.release_button(key.upper())
                elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
                    self.gamepad1.release_button(key.upper())
                    self.gamepad2.release_button(key.upper())
        else:
            # 键盘鼠标模式下触发键盘或鼠标按键
            # 处理键盘按键
            if key in self.reverse_mapping:
                # 如果这是一个映射的键盘/鼠标按键，触发对应的手柄按键
                gamepad_key = self.reverse_mapping[key]
                self._on_gamepad_key_event(gamepad_key, False)
            else:
                # 处理直接的键盘或鼠标按键
                self._direct_release_key(key)

    def _trigger_key(self, key):
        """
        触发指定按键（模拟按下并释放）

        :param key: 要触发的按键
        """
        # 根据当前模式触发按键
        if self.gamepad_mode in ["p1", "p2", "sync"]:
            # 手柄模式下触发手柄按键
            if key.upper() in self.GAMEPAD_BUTTONS:
                if self.gamepad_mode == "p1" and self.gamepad1:
                    self.gamepad1.btn_clicked(key.upper())
                elif self.gamepad_mode == "p2" and self.gamepad2:
                    self.gamepad2.btn_clicked(key.upper())
                elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
                    self.gamepad1.btn_clicked(key.upper())
                    self.gamepad2.btn_clicked(key.upper())

            elif key.upper() in self.JOYSTICK_BUTTONS:
                if self.gamepad_mode == "p1" and self.gamepad1:
                    self.gamepad1.press_button(key.upper())
                    time.sleep(0.05)  # 短暂延迟
                    self.gamepad1.release_button(key.upper())
                elif self.gamepad_mode == "p2" and self.gamepad2:
                    self.gamepad2.press_button(key.upper())
                    time.sleep(0.05)  # 短暂延迟
                    self.gamepad2.release_button(key.upper())
                elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
                    self.gamepad1.press_button(key.upper())
                    self.gamepad2.press_button(key.upper())
                    time.sleep(0.05)  # 短暂延迟
                    self.gamepad1.release_button(key.upper())
                    self.gamepad2.release_button(key.upper())
        else:
            # 键盘鼠标模式下触发键盘或鼠标按键
            # 处理键盘按键
            if key in self.reverse_mapping:
                # 如果这是一个映射的键盘/鼠标按键，触发对应的手柄按键
                gamepad_key = self.reverse_mapping[key]
                self._on_gamepad_key_event(gamepad_key, True)
                time.sleep(0.05)
                self._on_gamepad_key_event(gamepad_key, False)
            else:
                # 处理直接的键盘或鼠标按键
                self._trigger_direct_input(key)

    def _trigger_direct_input(self, key):
        """
        直接触发键盘或鼠标输入

        :param key: 要触发的按键
        """
        # 触发键盘按键
        if key.lower() in self.KEYBOARD_KEYS:
            k = self.KEYBOARD_KEYS[key.lower()]
            keyboard.Controller().press(k)
            time.sleep(0.05)
            keyboard.Controller().release(k)

        # 触发鼠标按键
        elif key in self.MOUSE_BUTTONS:
            button = self.MOUSE_BUTTONS[key]
            mouse.Controller().press(button)
            time.sleep(0.05)
            mouse.Controller().release(button)

    def start_listening(self):
        """
        启动键盘和鼠标监听
        """
        if self.is_listening:
            return  # 已经在监听中

        # 创建键盘监听器
        self.keyboard_listener = keyboard.Listener(
            on_press=self._on_keyboard_press,
            on_release=self._on_keyboard_release
        )

        # 启动监听器
        self.keyboard_listener.start()
        # self.mouse_listener.start()
        # 启动鼠标轮询线程
        self._start_mouse_polling()

        self.is_listening = True
        self.printToTerm("输入监听已启动")

    def _start_mouse_polling(self):
        """
        启动鼠标轮询线程
        """
        if not self.mouse_polling_active:
            self.mouse_polling_active = True
            self.mouse_polling_thread = threading.Thread(target=self._mouse_polling_worker, daemon=True)
            self.mouse_polling_thread.start()
            self.printToTerm("鼠标轮询线程已启动")

    def _mouse_polling_worker(self):
        """
        鼠标轮询工作线程
        """
        try:
            import win32api

            # 鼠标按键到虚拟键码的映射
            mouse_buttons = {
                '鼠标左键': 0x01,  # VK_LBUTTON
                '鼠标右键': 0x02,  # VK_RBUTTON
                '鼠标滚轮': 0x04,  # VK_MBUTTON
                '鼠标X1键': 0x05,  # VK_XBUTTON1
                '鼠标X2键': 0x06,  # VK_XBUTTON2
            }

            # 记录按键上一次的状态
            last_button_states = {button_name: False for button_name in mouse_buttons.keys()}

            while self.mouse_polling_active:
                # 检查每个我们关心的鼠标按键
                for button_name, vkey in mouse_buttons.items():
                    # 检查按键是否在映射中
                    if button_name in self.reverse_mapping:
                        # 获取当前按键状态
                        state = win32api.GetKeyState(vkey)
                        is_pressed = state < 0

                        # 如果状态发生变化
                        if is_pressed != last_button_states[button_name]:
                            gamepad_key = self.reverse_mapping[button_name]

                            if is_pressed:
                                # 按键被按下
                                self.printToTerm(f"检测到鼠标按键按下: {button_name} -> {gamepad_key}")
                                self._on_gamepad_key_event(gamepad_key, True)
                                self.held_mouse_buttons[button_name] = gamepad_key
                            else:
                                # 按键被释放
                                self.printToTerm(f"检测到鼠标按键释放: {button_name} -> {gamepad_key}")
                                self._on_gamepad_key_event(gamepad_key, False)
                                if button_name in self.held_mouse_buttons:
                                    del self.held_mouse_buttons[button_name]

                            # 更新状态记录
                            last_button_states[button_name] = is_pressed

                # 短暂休眠以控制轮询频率
                time.sleep(0.01)  # 100Hz轮询频率

        except ImportError:
            self.printToTerm("win32api未安装，无法使用鼠标轮询功能")
        except Exception as e:
            self.printToTerm(f"鼠标轮询线程出错: {e}")
            logger.error(f"鼠标轮询线程出错: {e}")
        finally:
            self.mouse_polling_thread = None

    def stop_listening(self):
        """
        停止键盘和鼠标监听
        """
        if not self.is_listening:
            return

        # 停止监听器
        if self.keyboard_listener:
            self.keyboard_listener.stop()

        if self.mouse_listener:
            self.mouse_listener.stop()

        self.is_listening = False
        self.printToTerm("输入监听已停止")

    @staticmethod
    def get_key_name(key):
        try:
            # 尝试获取字符键
            key_name = key.char.lower() if key.char else None
        except AttributeError:
            # 特殊键（如功能键、控制键等）
            if key.name == 'left':
                key_name = '←'
            elif key.name == 'up':
                key_name = '↑'
            elif key.name == 'right':
                key_name = '→'
            elif key.name == 'down':
                key_name = '↓'
            elif key.name == 'ctrl_l':
                key_name = 'lctrl'
            elif key.name == 'ctrl_r':
                key_name = 'rctrl'
            else:
                key_name = key.name.lower()
        return key_name

    def _on_keyboard_press(self, key: any):
        """
        键盘按键按下事件处理

        :param key: 按下的键
        """
        key_name = self.get_key_name(key)

        if not key_name:
            return

        # 检查是否是定时按键功能的快捷键，如果是定时按键功能的快捷键，则不管当前是什么模式，直接切换定时按键功能
        timed_key_hotkey = self.timed_key_press_settings.get('hotkey', '').lower()
        if key_name == timed_key_hotkey and timed_key_hotkey:
            self._toggle_timed_key_press()
            return

        # 检查是否是模式切换键
        mode_key_matched = False
        for mode_key in self.mode_keys.values():
            if isinstance(mode_key, list):
                if key_name in [k.lower() for k in mode_key if k]:
                    mode_key_matched = True
                    break
            else:
                if key_name == (mode_key.lower() if mode_key else None):
                    mode_key_matched = True
                    break
        if mode_key_matched:
            self._handle_mode_switch(key_name)
            return

        # 检查是否是映射的键
        if key_name in self.reverse_mapping:
            gamepad_key = self.reverse_mapping[key_name]
            self.pressed_keys.add(key_name)
            self._on_gamepad_key_event(gamepad_key, True)

    def _on_keyboard_release(self, key: any):
        """
        键盘按键释放事件处理

        :param key: 释放的键
        """
        key_name = self.get_key_name(key)

        if not key_name:
            return

        # 检查是否是映射的键
        if key_name in self.reverse_mapping and key_name in self.pressed_keys:
            gamepad_key = self.reverse_mapping[key_name]
            self.pressed_keys.discard(key_name)
            self._on_gamepad_key_event(gamepad_key, False)

    def _handle_mode_switch(self, key_name):
        """
        处理模式切换

        :param key_name: 模式切换键名称
        """
        # 查找对应的模式
        mode = None
        for m, k in self.mode_keys.items():
            matched = False
            if isinstance(k, list):
                # 如果k是列表，检查key_name是否在列表中
                for key_item in k:
                    if key_item and key_name == key_item.lower():
                        matched = True
                        break
            else:
                # 原来的单按键处理方式
                if k and key_name == k.lower():
                    matched = True

            if matched:
                mode = m
                break

        if mode:
            if mode == "p1":
                self._switch_to_p1_mode()
            elif mode == "p2":
                self._switch_to_p2_mode()
            elif mode == "sync":
                self._switch_to_sync_mode()
            elif mode == "keyboard":
                self._switch_to_keyboard_mode()
            elif mode == "toggleP1":
                self._toggle_p1_mode()
            elif mode == "toggleP2":
                self._toggle_p2_mode()

    def _switch_to_p1_mode(self):
        """
        切换到P1手柄模式
        """
        self.gamepad2.reset()  # 将P2手柄重置
        self.gamepad_mode = "p1"
        self.printToTerm("已切换到P1手柄模式")

    def _toggle_p1_mode(self):
        if self.gamepad_mode == "p1":
            self.gamepad1.reset()
            self.gamepad_mode = "keyboard"
        elif self.gamepad_mode == "p2":
            self.gamepad_mode = "sync"
        elif self.gamepad_mode == "sync":
            self.gamepad1.reset()
            self.gamepad_mode = "p2"
        elif self.gamepad_mode == "keyboard":
            self.gamepad_mode = "p1"

    def _toggle_p2_mode(self):
        if self.gamepad_mode == "p1":
            self.gamepad_mode = "sync"
        elif self.gamepad_mode == "p2":
            self.gamepad2.reset()
            self.gamepad_mode = "keyboard"
        elif self.gamepad_mode == "sync":
            self.gamepad2.reset()
            self.gamepad_mode = "p1"
        elif self.gamepad_mode == "keyboard":
            self.gamepad_mode = "p2"

    def _switch_to_p2_mode(self):
        """
        切换到P2手柄模式
        """
        self.gamepad_mode = "p2"
        self.gamepad1.reset()
        self.printToTerm("已切换到P2手柄模式")

    def _switch_to_sync_mode(self):
        """
        切换到同步模式（同时控制两个手柄）
        """
        self.gamepad_mode = "sync"
        self.printToTerm("已切换到同步手柄模式")

    def _switch_to_keyboard_mode(self):
        """
        切换回键盘鼠标模式
        """
        # 释放所有按下的按钮
        self.gamepad1.reset()
        self.gamepad2.reset()
        self._release_all_buttons()
        self.gamepad_mode = "keyboard"
        self.printToTerm("已切换回键盘鼠标模式")

    def _release_all_buttons(self):
        """释放所有按下的按钮"""
        if self.gamepad1:
            for button in self.gamepad1.button_map:
                self.gamepad1.release_button(button)

        if self.gamepad2:
            for button in self.gamepad2.button_map:
                self.gamepad2.release_button(button)

    def _on_gamepad_key_event(self, gamepad_key: str, is_press: bool):
        """
        处理游戏手柄按键事件

        :param gamepad_key: 游戏手柄按键名称
        :param is_press: 是否是按下事件
        """
        # 只在手柄模式下处理
        if self.gamepad_mode == "keyboard":
            return

        # 确保游戏手柄已初始化
        if not self.gamepad1 and not self.gamepad2:
            return

        if self.last_msg != f"按下手柄按键: {gamepad_key}":
            self.printToTerm(f"按下手柄按键: {gamepad_key}")

        # 根据当前模式处理按键
        if self.gamepad_mode == "p1" and self.gamepad1:
            if is_press:
                self.gamepad1.press_button(gamepad_key.upper())
            else:
                self.gamepad1.release_button(gamepad_key.upper())

        elif self.gamepad_mode == "p2" and self.gamepad2:
            if is_press:
                self.gamepad2.press_button(gamepad_key.upper())
            else:
                self.gamepad2.release_button(gamepad_key.upper())

        elif self.gamepad_mode == "sync" and self.gamepad1 and self.gamepad2:
            if is_press:
                self.gamepad1.press_button(gamepad_key.upper())
                self.gamepad2.press_button(gamepad_key.upper())
            else:
                self.gamepad1.release_button(gamepad_key.upper())
                self.gamepad2.release_button(gamepad_key.upper())
